<template>
  <el-menu
    :default-active="activeIndex"
    class="el-menu-demo"
    mode="horizontal"
    @select="handleSelect"
  >
    <el-menu-item index="1">Reftable Binary Explorer</el-menu-item>
  </el-menu>

    <el-container class="w-full h-full">      
    <el-aside class="overflow-auto left">
      <el-main class="w-full px-1">
        <file-list ref="filelist" @fileChanged="onFileChanged"/>
      </el-main>
    </el-aside>

    <el-aside class="overflow-auto center">
      <el-main class="w-full px-1">
        <reftable-summary :summary="summary"></reftable-summary>
        <el-card>
          <el-tabs v-model="activeTab" class="w-full" :border="true" type="border-card" @tab-click="onTabClicked">
            <el-tab-pane :label="tabLabels.firstBlock" name="FirstBlock">
              <reftable-header :data="reftable?.firstBlock?.header" :debug="reftable?.firstBlock?._debug.header" @clicked="onTableRowClicked"></reftable-header>
              <reftable-ref-block :data="reftable?.firstBlock?.block" :debug="reftable?.firstBlock?._debug.block" @clicked="onTableRowClicked"></reftable-ref-block>
            </el-tab-pane>

            <el-tab-pane :label="tabLabels.refBlock" name="Refs">
              <el-collapse accordion v-if="reftable?.otherRefBlocks?.records">
                <el-collapse-item :title="`Ref Block ${index + 1}`" :name="index" v-for="(item, index) in reftable?.otherRefBlocks?.records">
                  <reftable-ref-block :data="item" :debug="reftable?.otherRefBlocks?._debug?.records" @clicked="onTableRowClicked"></reftable-ref-block>
                </el-collapse-item>
              </el-collapse>
              <view v-else>
                <el-empty :image-size="200" />
              </view>
            </el-tab-pane>

            <el-tab-pane :label="tabLabels.refIndexBlock" name="RefIndex">
              <view v-if="reftable?.refIndexBlock?.indexRecords.records">
                <reftable-index-block :data="reftable?.refIndexBlock" :debug="reftable?._debug?.refIndexBlock" @clicked="onTableRowClicked"></reftable-index-block>
              </view>
              <view v-else>
                <el-empty :image-size="200" />
              </view>
            </el-tab-pane>

            <el-tab-pane :label="tabLabels.objectBlock" name="Objs">
              <el-collapse accordion v-if="reftable?.objectBlocks?.records">
                <el-collapse-item :title="`Object Block ${index + 1}`" :name="index" v-for="(item, index) in reftable?.objectBlocks?.records">
                  <reftable-object-block :data="item" :debug="reftable?.objectBlocks?._debug?.records" @clicked="onTableRowClicked"></reftable-object-block>
                </el-collapse-item>
              </el-collapse>
              <view v-else>
                <el-empty :image-size="200" />
              </view>
            </el-tab-pane>

            <el-tab-pane :label="tabLabels.objectIndexBlock" name="ObjIndex">
              <view v-if="reftable?.objectIndexBlock?.indexRecords.records">
                <reftable-index-block :data="reftable?.objectIndexBlock" :debug="reftable?._debug?.objectIndexBlock" @clicked="onTableRowClicked"></reftable-index-block>
              </view>
              <view v-else>
                <el-empty :image-size="200" />
              </view>
            </el-tab-pane>

            <el-tab-pane :label="tabLabels.logBlock" name="Logs">
              <el-collapse accordion v-if="reftable?.logBlocks?.records">
                <el-collapse-item :title="`Log Block ${index + 1}`" :name="index" v-for="(item, index) in reftable?.logBlocks?.records">
                  <reftable-log-block :data="item" :debug="reftable?.logBlocks?._debug?.records" @clicked="onTableRowClicked"></reftable-log-block>
                </el-collapse-item>
              </el-collapse>
              <view v-else>
                <el-empty :image-size="200" />
              </view>
            </el-tab-pane>

            <el-tab-pane :label="tabLabels.logIndexBlock" name="LogIndex">
              <view v-if="reftable?.logIndexBlock?.indexRecords.records">
                <reftable-index-block :data="reftable?.logIndexBlock" :debug="reftable?._debug?.logIndexBlock" @clicked="onTableRowClicked"></reftable-index-block>
              </view>
              <view v-else>
                <el-empty :image-size="200" />
              </view>
            </el-tab-pane>

            <el-tab-pane :label="tabLabels.footer" name="Footer">
              <reftable-footer :data="reftable?.footer" :debug="reftable?.footer?._debug" @clicked="onTableRowClicked"></reftable-footer>
            </el-tab-pane>
          </el-tabs>
        </el-card>
      </el-main>
    </el-aside>
    <el-aside class="overflow-auto right">
      <el-main class="w-full px-1">
        <hex-viewer :content="content" ref="hexviewer" />
      </el-main>
    </el-aside>
  </el-container>
</template>

<script>
import { nextTick } from 'vue';
import loadjs from 'loadjs';
import { ElLoading } from 'element-plus'
import FileList from './components/FileList.vue';
import HexViewer from './components/HexViewer.vue';
import ReftableSummary from './components/reftable/Summary.vue';
import ReftableHeader from './components/reftable/Header.vue';
import ReftableFooter from './components/reftable/Footer.vue';
import ReftableRefBlock from './components/reftable/RefBlock.vue';
import ReftableObjectBlock from './components/reftable/ObjectBlock.vue';
import ReftableLogBlock from './components/reftable/LogBlock.vue';
import ReftableIndexBlock from './components/reftable/IndexBlock.vue';

export default {
  components: {
    FileList,
    HexViewer,
    ReftableHeader,
    ReftableFooter,
    ReftableSummary,
    ReftableRefBlock,
    ReftableObjectBlock,
    ReftableLogBlock,
    ReftableIndexBlock,
  },
  data() {
    return {
      content: (new TextEncoder()).encode("Reftable-Viewer"),
      activeTab: 'FirstBlock',
      fullscreenLoading: true,
      reftable: {},
      summary: {},
    };
  },
  mounted() {
    let that = this;
    loadjs([
      '/libs/kaitai/pako_inflate.min.js',
      '/libs/kaitai/long.js',
      '/libs/tools/Formater.js',
      '/libs/kaitai/KaitaiStream.js',
      '/libs/kaitai/Varint.js',
      '/libs/kaitai/Deflate.js',
      '/libs/kaitai/InflateZlib.js',
      '/libs/kaitai/LogRefDecoder.js',
      '/libs/kaitai/RefDecoder.js',
      '/libs/kaitai/Reftable.js',
    ], {
      success: function() {
        nextTick(() => {
          that.$refs.filelist.loadFileByIndex(0);
        });              
      },
      async: false,
    });
  },
  methods: {
    onFileChanged(content) {
      // this.fullscreenLoading = true;
      const loadingInstance = ElLoading.service({
        fullscreen: true,
        text: "渲染中，请稍后...",
        background: "rgba(0, 0, 0, 0.7)",
      })
      let reftable = new Reftable(new KaitaiStream(content));
      reftable._read();
      console.log(reftable);

      this.activeTab = "FirstBlock";
      this.summary = this.getReftableSummaryData(reftable);

      setTimeout(() => {
        this.reftable = reftable;
        this.content = content;
        nextTick(() => {
          loadingInstance.close()
        });
      }, 500);
    },

    onTabClicked(data, ev) {
      
    },

    onTableRowClicked(row, column, event) {
      console.log("row", row, "column", column, "event", event);
      this.$refs.hexviewer.updateSelectedInde(row.debug.ioOffset + row.debug.start, row.debug.ioOffset + row.debug.end - 1);
    },
    
    getReftableSummaryData(data) {
      let result = {};
      result.refBlockCount = data.otherRefBlocks?.records.length || 0;
      result.objectBlockCount = data.objectBlocks?.records.length || 0;
      result.logBlockCount = data.logBlocks?.records.length || 0;

      result.refBlockCountTotal = result.refBlockCount;
      result.objectBlockCountTotal = result.objectBlockCount;
      result.logBlockCountTotal = result.logBlockCount;

      let count = 0;
      if (data.otherRefBlocks?.records) {
        for (let block of data.otherRefBlocks?.records) {
          count += block.refRecords.records.length;
        }
      }
      result.refRecordCount = count;

      count = 0;
      if (data.objectBlocks?.records) {
        for (let block of data.objectBlocks?.records) {
          count += block.objectRecords.records.length;
        }
      }
      result.objectRecordCount = count;

      count = 0;
      if (data.logBlocks?.records) {
        for (let block of data.logBlocks?.records) {
          count += block.zlibDeflate.logRecords.records.length;
        }
      }
      result.logRecordCount = count;
      
      if (data?.firstBlock?.block instanceof Reftable.RefBlock) {
        result.refBlockCountTotal = result.refBlockCount + 1;
        result.refRecordCount += data?.firstBlock?.block.refRecords.records.length;
      }
      if (data?.firstBlock?.block instanceof Reftable.ObjectBlock) {
        result.objectBlockCountTotal = result.objectBlockCount + 1;
        result.objectRecordCount += data?.firstBlock?.block.objectRecords.records.length;
      }
      if (data?.firstBlock?.block instanceof Reftable.LogBlock) {
        result.logBlockCountTotal = result.logBlockCount + 1;
        result.logRecordCount += data?.firstBlock?.block.zlibDeflate.logRecords.records.length;
      }

      result.refIndexCount = data.refIndexBlock?.indexRecords.records.length || 0;
      result.objectIndexCount = data.objectIndexBlock?.indexRecords.records.length || 0;
      result.logIndexCount = data.logIndexBlock?.indexRecords.records.length || 0;
      return result;
    },
  },
  computed: {
    tabLabels() {
      return {        
        firstBlock: "FirstBlock(1)",
        refBlock: `Refs(${this.summary.refBlockCount || 0})`,
        refIndexBlock: `RefIndex(${this.reftable.refIndexBlock ? 1 : 0})`,
        objectBlock: `Objs(${this.summary.objectBlockCount || 0})`,
        objectIndexBlock: `ObjIndex(${this.reftable.objectIndexBlock ? 1 : 0})`,
        logBlock: `Logs(${this.summary.logBlockCount || 0})`,
        logIndexBlock: `LogIndex(${this.reftable.logIndexBlock ? 1 : 0})`,
        footer: `Footer(1)`,
      }
    },
  },
};
</script>

<style>
::-webkit-scrollbar {
  display: none;
}

.left {
  width: 300px !important;
  height: 100%;
  overflow: auto;
}

.center {
  width: calc(100% - 950px) !important;
  height: 100%;
  overflow: auto;
}

.right {
  width: 650px !important;
  height: 100%;
  overflow: auto;
}
</style>
